home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / fax / src / port / generic / mkdepend < prev   
Text File  |  1994-08-01  |  6KB  |  232 lines

  1. #! /bin/sh
  2. #    $Header: /usr/people/sam/fax/port/generic/RCS/mkdepend,v 1.6 1994/02/28 14:27:40 sam Rel $
  3. #
  4. # FlexFAX Facsimile Software
  5. #
  6. # Copyright (c) 1990, 1991, 1992, 1993, 1994 Sam Leffler
  7. # Copyright (c) 1991, 1992, 1993, 1994 Silicon Graphics, Inc.
  8. # Permission to use, copy, modify, distribute, and sell this software and 
  9. # its documentation for any purpose is hereby granted without fee, provided
  10. # that (i) the above copyright notices and this permission notice appear in
  11. # all copies of the software and related documentation, and (ii) the names of
  12. # Sam Leffler and Silicon Graphics may not be used in any advertising or
  13. # publicity relating to the software without the specific, prior written
  14. # permission of Sam Leffler and Silicon Graphics.
  15. # THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  16. # EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  17. # WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  18. # IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
  19. # ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  20. # OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  21. # WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
  22. # LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
  23. # OF THIS SOFTWARE.
  24. #
  25. # NAME
  26. #    mkdepend - compute header file dependencies
  27. # SYNOPSIS
  28. #    mkdepend [-c compiler] [-e sedprog] [-f force] [-ipr] [-s sentinel]
  29. #        depfile file ...
  30. # DESCRIPTION
  31. #    See mkdepend(1).
  32. #
  33. me=$0
  34. usage="usage: $me [-c compiler] [-e sedprog] [-f force] [-ipr]\n\t[-s sentinel] depfile [file ...]"
  35. depgen="gcc -M"
  36. incremental=no
  37. rawdepinput=no
  38.  
  39. #
  40. # Process options and arguments.  We put quotes around the edit (-e) arguments
  41. # and use eval "sed -e ..." later, to preserve spaces in the edit command.
  42. #
  43. while getopts c:e:f:ip:rs: OPT; do
  44.     case $OPT in
  45.       c)    depgen=$OPTARG;;
  46.       e)    sedprog="$sedprog -e '$OPTARG'";;
  47.       f)    force="$force $OPTARG";;
  48.       i)    incremental=yes;;
  49.       p)    depgen=collapse pcount=$OPTARG rawdepinput=yes;;
  50.       r)    depgen=cat rawdepinput=yes;;
  51.       s)    sentinel=$OPTARG;;
  52.       *)    echo $usage; exit 2
  53.     esac
  54. done
  55. shift `expr $OPTIND - 1`
  56. case $# in
  57.   0)    echo $usage; exit 2
  58. esac
  59.  
  60. newdepfile=$1
  61. depfiledir=`dirname $1`
  62. olddepfile=$depfiledir/#`basename $1`
  63. shift
  64.  
  65. #
  66. # A shell function to collapse dependencies of targets in subdirectories
  67. # on common rightsides.
  68. #
  69. collapse() {
  70.     sed -e 's@/\([^/:]*\): @/%\1: @' $* |
  71.     sort -t% +1 |
  72.     uniq |
  73.     nawk -F: '
  74.     BEGIN {
  75.         total = '$pcount'
  76.     }
  77.     function flush(group, lastdir, dirname, count) {
  78.         for (dirname in group)
  79.             count++
  80.         if (count == total) {
  81.             print group[lastdir]
  82.         } else {
  83.             for (dirname in group)
  84.                 print dirname group[dirname]
  85.         }
  86.         for (dirname in group)
  87.             delete group[dirname]
  88.     }
  89.     {
  90.         percent = index($1, "%")
  91.         name = substr($1, percent + 1)
  92.         if (name != basename || $2 != rightside) {
  93.             flush(group, dirname)
  94.             basename = name
  95.             rightside = $2
  96.         }
  97.         dirname = substr($1, 1, percent - 1)
  98.         group[dirname] = basename ":" rightside
  99.     }
  100.     END {
  101.         flush(group, dirname)
  102.     }' |
  103.     sort
  104. }
  105.  
  106. #
  107. # An awk script to compress and pretty-print dependencies.
  108. #
  109. awkprog='
  110. BEGIN {
  111.     FS = ":"
  112.     INDENT = "\t"
  113.     INDENTSIZE = 8
  114.     MAXLINE = 72
  115.     MAXINDENTEDLINE = MAXLINE - INDENTSIZE - 1
  116. }
  117.  
  118. #
  119. # For each line of the form "target1 ... targetN: dependent", where the
  120. # spaces are literal blanks, do the following:
  121. #
  122. {
  123.     if ($1 != target) {
  124.         if (depline) print depline
  125.         target = $1
  126.         depline= $0 "'"$force"'"
  127.         lim = MAXLINE
  128.     } else {
  129.         if (length(depline) + length($2) > lim) {
  130.             print depline " \\"
  131.             depline = INDENT
  132.             lim = MAXINDENTEDLINE
  133.         }
  134.         depline = depline $2
  135.     }
  136. }
  137.  
  138. END {
  139.     if (depline) print depline 
  140. }'
  141.  
  142. #
  143. # Save the old file in case of problems.  Define some temporary files for
  144. # incremental make depend.  Clean up if interrupted.
  145. #
  146. olddeps=/tmp/olddeps.$$
  147. newdeps=/tmp/newdeps.$$
  148. tmpdeps=$depfiledir/tmpdeps.$$
  149. if test "$incremental" = yes; then
  150.     trapcmds="rm -f $olddeps $newdeps $tmpdeps;"
  151. fi
  152. if test -f "$newdepfile"; then
  153.     trapcmds="$trapcmds mv -f \\$olddepfile \\$newdepfile;"
  154.     ln $newdepfile $olddepfile
  155.     echo "# placeholder in case make includes me" > $tmpdeps
  156.     mv -f $tmpdeps $newdepfile
  157. fi
  158. trap "$trapcmds exit 0" 1 2 15
  159.  
  160. #
  161. # Remove any old dependencies from the file.
  162. #
  163. firstline="#$sentinel DO NOT DELETE THIS LINE -- make depend uses it"
  164. lastline="#$sentinel DO NOT DELETE THIS 2nd LINE -- make depend uses it"
  165.  
  166. if test -f "$olddepfile"; then
  167.     sed -e "/^$firstline/,/^$lastline/d" $olddepfile
  168. fi > $newdepfile
  169.  
  170. #
  171. # Delimit the beginning of the dependencies.  Save the old dependencies
  172. # in incremental mode.
  173. #
  174. echo $firstline >> $newdepfile
  175. if test $incremental = yes; then
  176.     #
  177.     # XXX Workaround for this sed bug: 1,/pat/d deletes 1,$ if line 1
  178.     # XXX and only line 1 matches pat.
  179.     #
  180.     (echo '# food for sed bug to eat'; cat $olddepfile 2> /dev/null) |
  181.         sed -e "1,/^$firstline/d" -e "/^$lastline/"',$d' > $olddeps
  182.  
  183.     #
  184.     # Compose an awk program that deletes pretty-printed dependencies
  185.     # from $olddeps that involve basenames of objects (in the raw input)
  186.     # or sources (arguments) whose dependencies are being updated.
  187.     #
  188.     awkinc='/^[^     ]/ { deleting = 0; }'
  189.     if test $rawdepinput = yes; then
  190.         cat $* > $newdeps
  191.         for f in `sed -e 's@^\([^:/]*\)\.[^:/]*: .*@\1@' \
  192.                   -e 's@^[^:]*/\([^:/]*\)\.[^:/]*: .*@\1@' \
  193.                   $newdeps |
  194.               sort -u`; do
  195.             list="$list $f"
  196.         done
  197.         set -- $newdeps
  198.     else
  199.         for f in $*; do
  200.             list="$list `expr ./$f : '.*/\(.*\)\..*'`"
  201.         done
  202.     fi
  203.     for f in $list; do
  204.         awkinc="$awkinc /^$f\./ || /^[^     :]*\/$f\./ { deleting = 1; }"
  205.     done
  206.     awkinc="$awkinc { if (!deleting) print \$0; }"
  207.     awk "$awkinc" $olddeps >> $newdepfile
  208.     rm -f $olddeps
  209. fi
  210.  
  211. #
  212. # Process source files - the sed commands and their functions are: 
  213. #    s:[^\./][^\./]*/\.\./::g    rewrite "dir/../path" to be "path"
  214. #    s:\([/ ]\)\./:\1:g        rewrite " ./path" to be " path" and
  215. #                    remove the "./" from  ".././h/x.h"
  216. #
  217. # (must escape some metacharacters for systems with busted shells)
  218. #$depgen $* |
  219. depgenxx=`echo $depgen|sed -e s/\'//g -e 's/(/\\(/g' -e 's/)/\\)/g'`
  220. $depgenxx $* |
  221.     eval "sed \
  222.     -e :loop -e 's:[^\./][^\./]*/\.\./::g' -e tloop \
  223.     -e 's:\([/ ]\)\./:\1:g' \
  224.     $sedprog" |
  225.     awk "$awkprog" >> $newdepfile
  226.  
  227. echo $lastline >> $newdepfile
  228. rm -f $olddepfile $newdeps
  229.